#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include <sys/timeb.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h> // file option
#include <dirent.h>
// #include <iostream>
// #include <sstream>
// #include <vector>
// #include <list>
// #include <map>
// #include <thread>
// #include <string>
// #include <iomanip>
// #include <fstream>
// #include <vector>
// #include <set>
// #include <algorithm>
// #include <unordered_map>
// #include <mutex>
// #include <atomic>
// #include <bits/wordsize.h>
// #include <bits/timesize.h>
using namespace std;

// 计算机储存：
// 位=1bit,最小储存单元，只能表示0,1。表示二进制。编程没有bit类型。
// 字节Byte=8bits,基本数据单位。比如内存条为1G，那就是1*1024*1024*1024byte的空间。
// 二进制：b01101001,对应十进制105，对应16进制0X69。可以通过计算器程序员模式查看。
// 二进制计算跟十进制类似：
//   b01011101
// + b11100011
// =b101000000
// char表示的有符号数，长度8bits，最高位0表示正，1表示负。他能表示-128到127
// uchar表示无符号数，0-255对应0x00-0xff
// 补码及作用：正数直接表示为二进制即可，负数为其正数取反加一。作用是加减法，计算器方便直接执行加运算。
// 2=b00000010
// -2则先用2=b00000010取反得到b11111101,然后加1得到b11111110。这就是计算机保存的内容。
// 试一下加法：2+(-2)=0
//   b00000010
// + b11111110
// =b000000000


//运行的空间：栈，堆，静态区，常量区，代码区(就是程序运行区)
//全局变量，分配在静态区，生命周期为整个程序运行期，不限于本文件。同进程的其他文件只要声明以下extern int gval;就能调用该全局变量了。
int gval1 = 0;
//静态变量，静态区，整个程序运行期，只限于本文件使用。
static int gval2 = 0;
//函数的形参与实参有各自的空间。
//v1，v2，v3是形参，有自己的空间，要跟实参区别开。
//v1,v2是局部变量，函数结束，被释放。
//v3是引用，可能是打破形参不能改变实参的特例，也就是传入参数的地址传送，v3不是局部变量，而是实际参数的空间。
int codeSpaceFunc(int v1, int *v2, int &v3, char *obuf)
{
    //静态变量，只作用于本函数。这里=1只会执行一次。
    static int gval3 = 1;
    gval3++;//每进入函数一次自加一次。
    int tmpval = 2;//局部变量，分配栈区，之作用本函数，生命周期只在本函数。本函数结束，被释放。
    printf("tmpval= %d\n", tmpval);
    //"123"处于常量区，不能修改
    char *tmpstr = "123";
    //tmpstr[0] = 'a';//tmpstr指向常量区，赋值会导致崩溃。
    printf("%s\n", tmpstr);
    if(v2)
    {
        free(v2);
        v2 = NULL;
    }
    {
        //tmpc局部变量值能在这个{}中使用，退出此{},他将被释放。
        int tmpc = 546;
        printf("%d\n", tmpc);
    }
    //malloc 分配的空间在堆，返回的指针在free或程序结束(不是函数结束)释放。如果malloc不free可能造成内存泄漏
    v2 = (int *)malloc(sizeof(int));
    v1 = 123;
    v3 = 321;
    gval1 = 1;
    gval2 = 2;
    //obuf的值不能改变，但指针内容可以改变！
    obuf[0] = 1;
    printf("func:%d,%d,%p:%d,%d,%d\n", v1, v3, v2, gval1, gval2, obuf[0]);
    return 1;
}
int main()
{
    int tmpv1 = 1, tmpv3 = 2;
    int *tmpv2 = NULL;
    char tbuf[10] = {0};
    printf("begin:%d,%d,%p:%d,%d,%d\n", tmpv1, tmpv3, tmpv2, gval1, gval2, tbuf[0]);
    //函数不能改变实参tmpv1的值，不能改变实参tmpv2的值，能改变实参tmpv3的值
    //参数传入函数时，函数会重新定义变量
    codeSpaceFunc(tmpv1, tmpv2, tmpv3, tbuf);
    printf("end:%d,%d,%p:%d,%d,%d\n", tmpv1, tmpv3, tmpv2, gval1, gval2, tbuf[0]);
    return 0;
}
//运行结果
// begin:1,2,(nil):0,0,0
// func:123,321,0x556c840e52c0:1,2,1
// end:1,321,(nil):1,2,1

